package com.apes.fn.scm.retailOrder.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.apes.fn.scm.retailOrder.model.BusinessOrderType;
import com.apes.fn.scm.retailOrder.model.BusinessType;
import com.apes.fn.scm.retailOrder.repository.TurnoverDao;
import com.apes.framework.api.DomainService;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.util.Arith;
import com.apes.framework.util.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;

/**
 * @BelongsProject: apes-server
 * @BelongsPackage: com.apes.fn.scm.retailOrder.service
 * @ClassName: TurnoverService
 * @Author: pyb
 * @Description: 营业额服务层
 * @CreateTime: 2021-06-17 10:02
 * @Version: 1.0
 */
@Service("turnoverService")
public class TurnoverService extends DomainService {

    @Autowired
    TurnoverDao turnoverDao;

    static Map<BusinessType, Function<JSONObject, JSONObject>> businessTypeMap = new HashMap<>(8);

    {
        businessTypeMap.put(BusinessType.ServicePerformance, this::servicePerformance);
        businessTypeMap.put(BusinessType.CardSale, this::cardSale);
        businessTypeMap.put(BusinessType.StoredValue, this::storedValue);
        businessTypeMap.put(BusinessType.Deposit, this::deposit);
        businessTypeMap.put(BusinessType.FundIncome, this::fundIncome);
        businessTypeMap.put(BusinessType.IntroductionFee, this::introductionFee);
        businessTypeMap.put(BusinessType.UsedCar, this::usedCar);
        businessTypeMap.put(BusinessType.Cross, this::Cross);
    }

    /**
     * 入口
     *
     * @param request
     * @return
     */
    public JSONObject entrance(SimpleRequest request) {
        JSONObject param = request.getJO();
        if (!param.containsKey("businessType")){
            throw new RuntimeException("businessType 参数必填！");
        }
        BusinessType businessType = BusinessType.getBusinessTypeByCode(param.getString("businessType"));
        if (Objects.isNull(businessType)) {
            throw new RuntimeException(String.format("参数businessType[%s]不合法！",param.getString("businessType")));
        }
        return businessTypeMap.get(businessType).apply(param);
    }


    /**
     * 服务业绩
     * (洗车金额+美容金额+保养金额+轮胎金额+维修金额+钣喷金额+改装金额+道路救援金额+精品金额+生活用品+技术检测+信息服务)
     *
     * @param param
     * @return
     */
    public JSONObject servicePerformance(JSONObject param) {
        JSONObject result = new JSONObject();
        JSONObject body = new JSONObject();
        if (!param.containsKey("param")) {
            throw new RuntimeException("参数字段必填！请检查传参！");
        }
        if (Objects.equals("Day", param.getString("param"))) {
            checkParam(param);
            //分页求数据
            JSONArray servicePerformance = turnoverDao.findServicePerformance(param);
            body.put("data", servicePerformance);
            //求合计和页数
            JSONArray servicePerformanceCount = turnoverDao.findServicePerformance_count(param);

            //求付款方式汇总 第一次请求时汇总
            if (param.getIntValue("page") == 1) {
                JSONArray summary = turnoverDao.findServicePerformance_summary(param);
                body.put("head", summary);
            }

            result.putAll(param);
            result.put("total", servicePerformanceCount.getJSONObject(0).getString("COUNT"));
            result.put("sum", servicePerformanceCount.getJSONObject(0).getString("SUM"));


        }
        if (Objects.equals("Month", param.getString("param"))) {
            if (!param.containsKey("YEAR_MONTH")) {
                throw new RuntimeException("日期与分页字段必填！请检查传参！");
            }
            SimpleDateFormat dtf = new SimpleDateFormat("yyyyMM");
            String yearMonth = param.getString("YEAR_MONTH");

            try {
                Date parse = dtf.parse(yearMonth);
                param.put("FIRST_DAY", parse);
                param.put("LAST_DAY", DateUtil.getMonthLastDay(parse));
                JSONArray servicePerformanceMonth = turnoverDao.findServicePerformanceMonth(param);
                body.put("data", servicePerformanceMonth);
                result.put("sum", servicePerformanceMonth.stream().map(m -> ((JSONObject) m).getDoubleValue("TOTAL")).reduce(Arith::add).orElse(0.0));
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        return getOrder(param, result, body);
    }

    /**
     * 年卡销售
     *
     * @param param
     * @return
     */
    public JSONObject cardSale(JSONObject param) {
        JSONObject result = new JSONObject();
        JSONObject body = new JSONObject();
        if (!param.containsKey("param")) {
            throw new RuntimeException("参数字段必填！请检查传参！");
        }
        if (Objects.equals("Day", param.getString("param"))) {
            checkParam(param);
            //分页求数据
            JSONArray data = turnoverDao.findCardSale(param);
            body.put("data", data);
            //求合计和页数
            JSONArray count = turnoverDao.findCardSale_count(param);

            //求付款方式汇总 第一次请求时汇总
            if (param.getIntValue("page") == 1) {
                JSONArray summary = turnoverDao.findCardSale_summary(param);
                body.put("head", summary);
            }

            result.putAll(param);
            result.put("total", count.getJSONObject(0).getString("COUNT"));
            result.put("sum", count.getJSONObject(0).getString("SUM"));


        }
        if (Objects.equals("Month", param.getString("param"))) {
            if (!param.containsKey("YEAR_MONTH")) {
                throw new RuntimeException("日期与分页字段必填！请检查传参！");
            }
            SimpleDateFormat dtf = new SimpleDateFormat("yyyyMM");
            String yearMonth = param.getString("YEAR_MONTH");

            try {
                Date parse = dtf.parse(yearMonth);
                param.put("FIRST_DAY", parse);
                param.put("LAST_DAY", DateUtil.getMonthLastDay(parse));
                JSONArray cardSaleMonth = turnoverDao.findCardSaleMonth(param);
                body.put("data", cardSaleMonth);
                result.put("sum", cardSaleMonth.stream().map(m -> ((JSONObject) m).getDoubleValue("TOTAL")).reduce(Arith::add).orElse(0.0));
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        return getOrder(param, result, body);
    }


    /**
     * 储值
     *
     * @param param
     * @return
     */
    public JSONObject storedValue(JSONObject param) {
        JSONObject result = new JSONObject();
        JSONObject body = new JSONObject();
        if (!param.containsKey("param")) {
            throw new RuntimeException("参数字段必填！请检查传参！");
        }
        if (Objects.equals("Day", param.getString("param"))) {
            checkParam(param);
            //分页求数据
            JSONArray data = turnoverDao.findStoredValue(param);
            body.put("data", data);
            //求合计和页数
            JSONArray count = turnoverDao.findStoredValue_count(param);

            //求付款方式汇总 第一次请求时汇总
            if (param.getIntValue("page") == 1) {
                JSONArray summary = turnoverDao.findStoredValue_summary(param);
                body.put("head", summary);
            }

            result.putAll(param);
            result.put("total", count.getJSONObject(0).getString("COUNT"));
            result.put("sum", count.getJSONObject(0).getString("SUM"));


        }
        if (Objects.equals("Month", param.getString("param"))) {
            if (!param.containsKey("YEAR_MONTH")) {
                throw new RuntimeException("日期与分页字段必填！请检查传参！");
            }
            SimpleDateFormat dtf = new SimpleDateFormat("yyyyMM");
            String yearMonth = param.getString("YEAR_MONTH");

            try {
                Date parse = dtf.parse(yearMonth);
                param.put("FIRST_DAY", parse);
                param.put("LAST_DAY", DateUtil.getMonthLastDay(parse));
                JSONArray cardSaleMonth = turnoverDao.findStoredValueMonth(param);
                body.put("data", cardSaleMonth);
                result.put("sum", cardSaleMonth.stream().map(m -> ((JSONObject) m).getDoubleValue("TOTAL")).reduce(Arith::add).orElse(0.0));
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        return getOrder(param, result, body);
    }


    /**
     * 订金
     * 订金充值-订金消费
     * @param param
     * @return
     */
    public JSONObject deposit(JSONObject param) {
        JSONObject result = new JSONObject();
        JSONObject body = new JSONObject();
        if (!param.containsKey("param")) {
            throw new RuntimeException("参数字段必填！请检查传参！");
        }
        if (Objects.equals("Day", param.getString("param"))) {
            checkParam(param);
            //分页求数据
            JSONArray data = turnoverDao.findDeposit(param);
            body.put("data", data);
            //求合计和页数
            JSONArray count = turnoverDao.findDeposit_count(param);

            //求付款方式汇总 第一次请求时汇总
            if (param.getIntValue("page") == 1) {
                JSONArray summary = turnoverDao.findDeposit_summary(param);
                body.put("head", summary);
            }

            result.putAll(param);
            result.put("total", count.getJSONObject(0).getString("COUNT"));
            result.put("sum", count.getJSONObject(0).getString("SUM"));


        }
        if (Objects.equals("Month", param.getString("param"))) {
            if (!param.containsKey("YEAR_MONTH")) {
                throw new RuntimeException("日期与分页字段必填！请检查传参！");
            }
            SimpleDateFormat dtf = new SimpleDateFormat("yyyyMM");
            String yearMonth = param.getString("YEAR_MONTH");

            try {
                Date parse = dtf.parse(yearMonth);
                param.put("FIRST_DAY", parse);
                param.put("LAST_DAY", DateUtil.getMonthLastDay(parse));
                JSONArray monthData = turnoverDao.findDepositMonth(param);
                body.put("data", monthData);
                result.put("sum", monthData.stream().map(m -> ((JSONObject) m).getDoubleValue("TOTAL")).reduce(Arith::add).orElse(0.0));
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        return getOrder(param, result, body);
    }


    /**
     * 资金收入
     * @param param
     * @return
     */
    public JSONObject fundIncome(JSONObject param) {
        JSONObject result = new JSONObject();
        JSONObject body = new JSONObject();
        if (!param.containsKey("param")) {
            throw new RuntimeException("参数字段必填！请检查传参！");
        }
        if (Objects.equals("Day", param.getString("param"))) {
            checkParam(param);
            //分页求数据
            JSONArray data = turnoverDao.findFundIncome(param);
            body.put("data", data);
            //求合计和页数
            JSONArray count = turnoverDao.findFundIncome_count(param);

            //求付款方式汇总 第一次请求时汇总
            if (param.getIntValue("page") == 1) {
                JSONArray summary = turnoverDao.findFundIncome_summary(param);
                body.put("head", summary);
            }

            result.putAll(param);
            result.put("total", count.getJSONObject(0).getString("COUNT"));
            result.put("sum", count.getJSONObject(0).getString("SUM"));


        }
        if (Objects.equals("Month", param.getString("param"))) {
            if (!param.containsKey("YEAR_MONTH")) {
                throw new RuntimeException("日期与分页字段必填！请检查传参！");
            }
            SimpleDateFormat dtf = new SimpleDateFormat("yyyyMM");
            String yearMonth = param.getString("YEAR_MONTH");

            try {
                Date parse = dtf.parse(yearMonth);
                param.put("FIRST_DAY", parse);
                param.put("LAST_DAY", DateUtil.getMonthLastDay(parse));
                JSONArray monthData = turnoverDao.findFundIncomeMonth(param);
                body.put("data", monthData);
                result.put("sum", monthData.stream().map(m -> ((JSONObject) m).getDoubleValue("TOTAL")).reduce(Arith::add).orElse(0.0));
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        return getOrder(param, result, body);
    }



    /**
     * 接案介绍费
     * @param param
     * @return
     */
    public JSONObject introductionFee(JSONObject param) {
        JSONObject result = new JSONObject();
        JSONObject body = new JSONObject();
        if (!param.containsKey("param")) {
            throw new RuntimeException("参数字段必填！请检查传参！");
        }
        if (Objects.equals("Day", param.getString("param"))) {
            checkParam(param);
            //分页求数据
            JSONArray data = turnoverDao.findIntroductionFee(param);
            body.put("data", data);
            //求合计和页数
            JSONArray count = turnoverDao.findIntroductionFee_count(param);
            result.putAll(param);
            result.put("total", count.getJSONObject(0).getString("COUNT"));
            result.put("sum", count.getJSONObject(0).getString("SUM"));


        }
        if (Objects.equals("Month", param.getString("param"))) {
            if (!param.containsKey("YEAR_MONTH")) {
                throw new RuntimeException("日期与分页字段必填！请检查传参！");
            }
            SimpleDateFormat dtf = new SimpleDateFormat("yyyyMM");
            String yearMonth = param.getString("YEAR_MONTH");

            try {
                Date parse = dtf.parse(yearMonth);
                param.put("FIRST_DAY", parse);
                param.put("LAST_DAY", DateUtil.getMonthLastDay(parse));
                JSONArray monthData = turnoverDao.findIntroductionFeeMonth(param);
                body.put("data", monthData);
                result.put("sum", monthData.stream().map(m -> ((JSONObject) m).getDoubleValue("TOTAL")).reduce(Arith::add).orElse(0.0));
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        return getOrder(param, result, body);
    }
    /**
     * 二手车佣金
     * @param param
     * @return
     */
    public JSONObject usedCar(JSONObject param) {
        JSONObject result = new JSONObject();
        JSONObject body = new JSONObject();
        if (!param.containsKey("param")) {
            throw new RuntimeException("参数字段必填！请检查传参！");
        }
        if (Objects.equals("Day", param.getString("param"))) {
            checkParam(param);
            //分页求数据
            JSONArray data = turnoverDao.findUsedCar(param);
            body.put("data", data);
            //求合计和页数
            JSONArray count = turnoverDao.findUsedCar_count(param);
            result.putAll(param);
            result.put("total", count.getJSONObject(0).getString("COUNT"));
            result.put("sum", count.getJSONObject(0).getString("SUM"));


        }
        if (Objects.equals("Month", param.getString("param"))) {
            if (!param.containsKey("YEAR_MONTH")) {
                throw new RuntimeException("日期与分页字段必填！请检查传参！");
            }
            SimpleDateFormat dtf = new SimpleDateFormat("yyyyMM");
            String yearMonth = param.getString("YEAR_MONTH");

            try {
                Date parse = dtf.parse(yearMonth);
                param.put("FIRST_DAY", parse);
                param.put("LAST_DAY", DateUtil.getMonthLastDay(parse));
                JSONArray monthData = turnoverDao.findUsedCarMonth(param);
                body.put("data", monthData);
                result.put("sum", monthData.stream().map(m -> ((JSONObject) m).getDoubleValue("TOTAL")).reduce(Arith::add).orElse(0.0));
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        return getOrder(param, result, body);
    }


    /**
     * 跨公司结算
     * @param param
     * @return
     */
    public JSONObject Cross(JSONObject param) {
        JSONObject result = new JSONObject();
        JSONObject body = new JSONObject();
        if (!param.containsKey("param")) {
            throw new RuntimeException("参数字段必填！请检查传参！");
        }
        if (Objects.equals("Day", param.getString("param"))) {
            checkParam(param);
            //分页求数据
            JSONArray data = turnoverDao.findCross(param);
            body.put("data", data);
            //求合计和页数
            JSONArray count = turnoverDao.findCross_count(param);
            result.putAll(param);
            result.put("total", count.getJSONObject(0).getString("COUNT"));
            result.put("sum", count.getJSONObject(0).getString("SUM"));


        }
        if (Objects.equals("Month", param.getString("param"))) {
            if (!param.containsKey("YEAR_MONTH")) {
                throw new RuntimeException("日期与分页字段必填！请检查传参！");
            }
            SimpleDateFormat dtf = new SimpleDateFormat("yyyyMM");
            String yearMonth = param.getString("YEAR_MONTH");

            try {
                Date parse = dtf.parse(yearMonth);
                param.put("FIRST_DAY", parse);
                param.put("LAST_DAY", DateUtil.getMonthLastDay(parse));
                JSONArray monthData = turnoverDao.findCrossMonth(param);
                body.put("data", monthData);
                result.put("sum", monthData.stream().map(m -> ((JSONObject) m).getDoubleValue("TOTAL")).reduce(Arith::add).orElse(0.0));
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        return getOrder(param, result, body);
    }

    /**
     * 获取订单或者直接返回
     * @param param
     * @param result
     * @param body
     * @return
     */
    public JSONObject getOrder(JSONObject param, JSONObject result, JSONObject body) {
        if (Objects.equals("Order", param.getString("param"))) {
            if (!param.containsKey("ID") || !param.containsKey("INNER_BUSINESS_TYPE")) {
                throw new RuntimeException("订单详情中编码与类型字段必填！请检查传参！");
            }
            //单据明细
            JSONArray order = turnoverDao.findOrder(param);
            //收款明细
            JSONArray payMethod = turnoverDao.findOrderPayMethod(param);
            body.put("data", order);
            body.put("head", payMethod);
            body.put("title", BusinessOrderType.getBusinessOrderTypeByOrderType(param.getString("INNER_BUSINESS_TYPE")).getOrderTypeName() + "_" + param.getString("ID"));
            result.put("sum", order.stream().map(m -> ((JSONObject) m).getDoubleValue("PRICE_TOTAL")).reduce(Arith::add).orElse(0.0));
//            result.put("INNER_BUSINESS_TYPE",param.containsKey("INNER_BUSINESS_TYPE"));
        }

        result.put("body", body);
        return result;
    }


    /**
     * 检查参数
     * @param param
     */
    public void checkParam(JSONObject param) {
        if (!param.containsKey("DAY_DATE") || !param.containsKey("page") || !param.containsKey("size")) {
            throw new RuntimeException("日期与分页字段必填！请检查传参！");
        }
        int page = param.getIntValue("page");
        int size = param.getIntValue("size");
        param.put("start", (page - 1) * size);
        param.put("end", page * size);
        param.put("SETTLE_DATE", param.getDate("DAY_DATE"));
    }


}